package com.gagakuai.concurrent;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CancellationException;

/*
 * @program: common-starters
 * @description: 抽象实现
 * <p>
 * 任务执行框架】有两个重要的子类：【线程池】ThreadPoolExecutor与【任务池】ForkJoinPool
 * @author: houhong
 * @create: 2023-02-19 20:05
 */
public abstract class AbstractExecutorService implements ExecutorService {

    /*▼ 包装任务 ████████████████████████████████████████████████████████████████████████████████┓ */


    /*
     * 将runabable 包装为 FutureTask
     */
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {

        return new FutureTask<>(runnable, value);
    }

    /*
     * 将一个Callable包装成FutureTask
     */
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {

        return new FutureTask<T>(callable);
    }


    /*▼ 包装/提交/执行任务 ████████████████████████████████████████████████████████████████████████████████┓ */


    /*
     * 包装/提交/执行Callable型的任务
     */
    @Override
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) {
            throw new NullPointerException();
        }
        RunnableFuture<T> fTask = newTaskFor(task);
        execute(fTask);
        return fTask;
    }

    /*
     * 包装/提交/执行Runnable型的任务，不带返回值
     */
    @Override
    public Future<?> submit(Runnable task) {

        if (task == null) {
            throw new NullPointerException();
        }
        RunnableFuture<Void> fTask = newTaskFor(task, null);
        execute(fTask);
        return fTask;

    }

    /*
     * 包装/提交/执行Runnable型的任务，预设一个返回结果
     */

    @Override
    public <T> Future<T> submit(Runnable task, T result) {

        if (task == null) {
            throw new NullPointerException();
        }
        RunnableFuture<T> fTask = newTaskFor(task, result);
        execute(fTask);
        return fTask;

    }

    /*
     * 执行指定容器中的所有任务，返回值是所有包装后的任务列表
     */
    @Override
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {

        if (tasks == null) {
            throw new NullPointerException();
        }

        List<Future<T>> futures = new ArrayList<>(tasks.size());

        try {
            // 将容器中的Callable型任务批量转换为Future，并执行它们
            for (Callable<T> future : tasks) {
                RunnableFuture<T> tRunnableFuture = newTaskFor(future);
                futures.add(tRunnableFuture);
                execute(tRunnableFuture);
            }

            // 遍历所有任务，如果任务未结束，等待/促进任务结束，并获取任务的计算结果
            for (Future<T> future : futures) {
                //当前任务没有完成。阻塞等待
                if (!future.isDone()) {
                    try {
                        future.get();
                    } catch (CancellationException ignore) {
                    }
                }
            }

        } catch (Throwable t) {
            cancelAll(futures);
        } finally {
            //// TODO: 2023/2/19
        }


        return null;
    }



    /*▼ 中止任务 ████████████████████████████████████████████████████████████████████████████████┓ */

    private static <T> void cancelAll(List<Future<T>> futures) {
        cancelAll(futures, 0);
    }

    /*
     * 从指定容器的下标j开始，中止后续所有任务（设置中断标记）
     */
    private static <T> void cancelAll(List<Future<T>> futures, int j) {
        for (int size = futures.size(); j < size; j++) {
            futures.get(j).cancel(true);
        }
    }


}